import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;


import antrl.SysYLexer;
import antrl.SysYParser;

import backend.Code;
import backend.RISCVBuilder;
import backend.alloctor.GraphColoring_RegisterAllocator;
import backend.component.RISCVmodule;
import backend.Register.initReg;
import backend.opt.RISCVOptimize;
import backend.opt.RISCVScheduler;
import backend.opt.branchFolding;
import backend.opt.removeUselessReg;
import config.ArgParser;
import config.Config;
import midend.IR_Instruction.Instruction;
import midend.IR_Module;
import midend.IR_Optimizer.*;
import midend.IR_Value.IR_BaseBlock;
import midend.IR_Value.IR_FuncBlock;
import midend.IR_Visitor;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

import static java.lang.Thread.sleep;

public class Compiler {

    public static void main(String[] args) throws IOException {
        ArgParser argParser = new ArgParser(args);
        argParser.parseArgs();

        String inputFile = Config.inputFile;

        CharStream input = null;

        try (Reader fileReader = new FileReader(inputFile)) {  // 自动关闭资源
            input = CharStreams.fromReader(fileReader);
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("Error reading file: " + inputFile);
            System.exit(1); // 严重错误时退出
        }

        //词法分析
        SysYLexer lexer = new SysYLexer(input);
        BufferedTokenStream tokens = new BufferedTokenStream(lexer);


        //语法分析
        SysYParser parser = new SysYParser(tokens);
        ParseTree tree = parser.program(); // begin parsing at init rule


        //中间代码生成
        IR_Visitor visitor = new IR_Visitor(inputFile);
        visitor.visit(tree);

        IR_Module module = visitor.get_module();

        //中间代码保存检测
        // 生成IR后进行优化
        visitor.optimize_Module();

        //设置退出块
        module.setExitBlock(visitor.getBuilder());

        Optimizer_Factory optimizerFactory = new Optimizer_Factory(visitor.get_module(),Arrays.asList(new Mem_To_Reg()));
        for (IR_FuncBlock function : module.getFuncBlocks()) {
            optimizerFactory.optimize(function);
        }
        //后续相关函数块 基本块关系的处理
        module.genRelation();

        //生成文件
        module.buildCFG();
        IR_Module.IR_Code_To_File(module, Config.lloutputFile);

        Remove_phi removePhi2 = new Remove_phi(module);
        removePhi2.run();

        module.simplyBBRelation();
        module.mergeBB();

        DeadCode_Eli DCE = new DeadCode_Eli(module);
        DCE.Optimize();


        //初始化 寄存器列表
        initReg.init();

        //首先使用虚拟寄存器转 riscv代码
        Code code = new Code(visitor.get_module());
        RISCVmodule asmModule = code.run();

        //删除后续不会使用到的寄存器，减轻图着色算法的负担
        removeUselessReg removeNoUseRegTool = new removeUselessReg(asmModule);
        removeNoUseRegTool.run();

        //分配实际的寄存器
        GraphColoring_RegisterAllocator regAllocaMonitor = new GraphColoring_RegisterAllocator(asmModule);
        regAllocaMonitor.run();

        RISCVOptimize riscvop = new RISCVOptimize(asmModule);
        riscvop.run();

        RISCVScheduler riscvScheduler = new RISCVScheduler(asmModule);
        riscvScheduler.run();

        RISCVBuilder dumpTool = new RISCVBuilder(Config.outputFile);
        dumpTool.dumpRISC_V(asmModule);
    }
}